/* Author: Vincent Acuna
	Class: Game

	Notes:
	-This version of game was programed to deal with board names in terms of ints
	instead of Strings. It was much easier to deal with Boards in terms of integers
	because the ArrayList position will also coorespond with the Board "name".

We need to add a method into the chain UIController -> LogicController ->
Game -> Rules called getPieceCounts that would return an ArrayList<Integer>
containing the # of each type of piece
(Checker,King,Mine,BlockedZone,SafeZone) that the current player can still
place.

*/

import java.util.*;
import java.awt.*;


public class Game
{
		Player first, //represents player that moved first
                       currentPlayer; //represents the current player
		Move currentMove;
		Rules checkers;//Rules object for the Game
		Piece lastPiece;//will be used to represent the previous piece
		ArrayList<Player> sortedplayers = new ArrayList<Player>(2); // will be sorted
		ArrayList<Player> players = new ArrayList<Player>(2); //Array list of players playing this game
		ArrayList<Board> boards = new ArrayList<Board>();//Array list of boards that the players play on
		Dimension boardsSize;
		MovesLog gameMoves= new MovesLog(); //The moves log
		int moveNumber; //keeps track of chains
		/*the following will be used to keep track of:
		 * Total Moves
		 * warps
		 * jumps
		 * Kings Created
		 * Kings Destroyed
		 For both players
		 */
		int tm1,w1,j1,kc1,kd1,tm2,w2,j2,kc2,kd2;
		ArrayList<Move> AvailableMoves;
                Date startDate, lastSaved;
                Boolean finished;
 //keeps track of jumps,mine explosions, turns
	public Game()//Constructor for Game object
	{
		System.out.println("GAME: constructing a new game...");
		checkers = new Rules(boards);
		moveNumber = 1;
                startDate = lastSaved = new Date();
                finished = false;
	}

	//convenience method that will take the temporary game stats and add them to the permanent player stats
	public void updateGameplayStats() {
		
		this.players.get(0).stats.jumps += this.j1;
		this.players.get(0).stats.kingscreated += this.kc1;
		this.players.get(0).stats.kingsdestroyed += this.kd1;
		this.players.get(0).stats.movestotal += this.tm1;
		this.players.get(0).stats.warps += this.w1;
		this.players.get(1).stats.jumps += this.j2;
		this.players.get(1).stats.kingscreated += this.kc2;
		this.players.get(1).stats.kingsdestroyed += this.kd2;
		this.players.get(1).stats.movestotal += this.tm2;
		this.players.get(1).stats.warps += this.w2;
		
	}
	

	public ArrayList<Piece> getMovablePieces() //this method essentially only calls rules and returns the result
	{
		//logical outline for this method
		/*
		retrieve movable pieces from rules
		~check if it is end of game is GUI's job now?
		if movable pieces is empty
			print a message for testing consideration
		return movable pieces
		*/
		ArrayList<Piece> movables = checkers.getMovablePieces();
		if (movables.isEmpty()){
			System.out.println("GAME: movables is empty!");
		}
		return movables;
	}


	public Board getBoard(int board)//Takes an integer as input representing the board
	{
		/*With how the addBoards method adds boards, the board name
		should correspond with the index at which it is added into
		the array*/
		return boards.get(board);
	}

	public ArrayList<Move> getAvailableMoves(Piece currentPiece) //Again, only passes information around
	{
		//logical outline for this method
		/*
		~match the input piece with a real piece from the board
		for each possible piece at the input piece location
			if the possible piece has the same type as the input piece
				if the possible piece has the same owner as the input piece
					extract the real piece to take the place of the input piece
		~verify the real piece is owned by the current player
		if the real piece is not owned by the current player
			if the temporary last piece has a reference
				reset the temporary last piece has jumped and has warped attributes to false
				throw away the temporary last piece reference
			return an empty list of available moves
		retrieve available moves from rules
		~check if it is next turn
		if available moves is empty then the current player turn has ended
			if the temporary last piece has a reference
				reset the temporary last piece has jumped and has warped attributes to false
				throw away the temporary last piece reference
			tell moves log to prepare for the next turn
			reset the move number to 0
			set the current player to the next one
		if available moves is not empty then the current player turn is continuing
		return the available moves
		*/
		
		System.out.println("GAME: getting available move for movenumber=" + this.moveNumber);
		//match the input piece with a real piece from the board
		LinkedList<Piece> possibles = this.getBoard(currentPiece.location.board).getPieces(currentPiece.location);
		System.out.println("GAME: matching input piece with board piece");
		for (int i=0; i<possibles.size(); ++i){
			if (possibles.get(i).getClass().getName().equals(currentPiece.getClass().getName())){
				System.out.println("GAME: both pieces are of type " + currentPiece.getClass().getName());
				if (possibles.get(i).owner.equals(currentPiece.owner)){
					System.out.println("GAME: both pieces are owned by " + currentPiece.owner);
					currentPiece = possibles.get(i);
				}
			}
		}
		System.out.println("GAME: matched piece has warped=" + currentPiece.hasWarped + " ~ matched piece has jumped=" + currentPiece.hasJumped);
		//~verify the real piece is owned by the current player
		if (!currentPiece.owner.equals(currentPlayer.getName())){
			//reset the previous Piece's hasJumped, and hasWarped
			if(lastPiece != null){
				System.out.println("GAME: lastPiece reference found -> board=" + lastPiece.location.board + " , position = " + lastPiece.location);
				this.getBoard(lastPiece.location.board).getPieces(lastPiece.location).get(0).hasJumped=false;
				this.getBoard(lastPiece.location.board).getPieces(lastPiece.location).get(0).hasWarped=false;
				lastPiece = null;
			}
			//return an empty list of available moves
			this.AvailableMoves = new ArrayList<Move>();
			return this.AvailableMoves;
		}
		this.AvailableMoves=checkers.getAvailableMoves(currentPiece,moveNumber);
		if (AvailableMoves.isEmpty()){
			System.out.println("GAME: availmoves is empty!");
			//reset the previous Piece's hasJumped, and hasWarped
			if(lastPiece != null){
				System.out.println("GAME: lastPiece reference found -> board=" + lastPiece.location.board + " , position = " + lastPiece.location);
				this.getBoard(lastPiece.location.board).getPieces(lastPiece.location).get(0).hasJumped=false;
				this.getBoard(lastPiece.location.board).getPieces(lastPiece.location).get(0).hasWarped=false;
				lastPiece = null;
			}
			//it is a new turn
			gameMoves.nextTurn();
			if(currentPlayer.equals(players.get(1)))
			{
				setPlayer(0);
			}
			else
			{
				setPlayer(1);
			}
			moveNumber=1;
		}else{
			//++moveNumber;
		}
		for (int i=0; i<this.AvailableMoves.size(); ++i){
			System.out.println("GAME: AvailableMoves[" + i + "]=" + this.AvailableMoves.get(i).locations.get(this.AvailableMoves.get(i).locations.size()-1));
		}
		//testing stationary move
		/*
		if (this.AvailableMoves.size() > 0){
			ArrayList<Point> dummyPoints = new ArrayList<Point>();
			dummyPoints.add(currentPiece.location.position);
			dummyPoints.add(currentPiece.location.position);
			ArrayList<Integer> dummyBoards = new ArrayList<Integer>();
			dummyBoards.add(new Integer(currentPiece.location.board));
			dummyBoards.add(new Integer(currentPiece.location.board));
			Move dummyMove = new Move(dummyPoints, dummyBoards, false, false);
			this.AvailableMoves.add(dummyMove);
		}
		*/
		return this.AvailableMoves;
	}


	public Boolean addPiece(Piece desiredPiece, Board desiredBoard)
	{
		/*The point and location are derived from the Piece and Location class. The Piece
		Class has a Location called "position", and the Location class has a
		point called "position".*/

		Point additionPoint = desiredPiece.location;
		Location additionLoc= desiredPiece.location;

		/*The if statement verifies that at least 1 piece is available to be added(from getPiecesAvailable)
		,and also that the position is open(from validateAddition) and then proceeds to add the piece*/
		if(currentPlayer.getName().equals(desiredPiece.getOwner()))
		{
                        String err = checkers.validateAddition(additionLoc, desiredPiece);
			if(err == null)
			{
				desiredBoard.addPiece(desiredPiece,additionPoint);
				if(currentPlayer.equals(players.get(1)))
				{
					currentPlayer=players.get(0);
					setPlayer(0);
				}
				else
				{
					currentPlayer=players.get(1);
					setPlayer(1);
				}
				return true;
			}
		}

		return false;

	}

	public void setFirst(int index)
	{
		first = players.get(index);
	}

	public String getFirst()
	{
		return first.getName();
	}


/*The makeMove method should change the board to reflect the move that the player
 * has chosen. Before this the GUI should have called getAvailableMoves for the piece
 * and thus no invalid moves should have gotten to this point. All that is left to do
 * is make the required move.
 */

	public ArrayList<String> makeMove(Move newMove,Piece currentPiece)
	{
		
		//logical outline of this method...
		/*
		match move sent to us with our existing list of AvailableMoves
		if cannot match
			print a message informing about this strange situation which likely indicates an error
			send back an empty list of move properties
		if matched
			add the move to the moves log
			~update stats and counters to reflect the move that is about to be made
			~make the move in parallel to updating the stats in counters
			increment the total moves stat for the current player
			increment the move number
			~check for jumps
			if move locations size is larger than 2 then there is a jump
				for each jumped location in the move locations
					increment the jumps stat for the current player
					~peek at what was jumped
					for each piece residing on the board at the jumped location
						~check for jumped kings
						if the piece owner is not the current player
							if the piece is jumpable
								if the piece is a king
									increment the kings destroyed stat for the current player
								add the piece to the list of jumped pieces
								remove the piece from the board
								stop looking through pieces at this jumped location
			~move the piece
			for each piece residing on the board at the starting location
				if the piece owner is the current player
					if the piece can move (move range larger thn 0)
						if move locations size is larger than 2 then there was a jump
							update the piece has jumped property to true
						temporarily store a copy of the piece
						remove the piece from the board
						stop looking through pieces at the starting location
			~check if we warped
			if the move destination location board is not the same as the move starting location board
				update the temporary moved piece has warped property to true
				increment the warps stat for the current player
			~decide if we need to place the piece
			if this move did not cause the piece to hit a mine
				~check if we need to change the piece
				if this move caused the piece to transform into a king and the piece is not already a king
					increment the kings created stat for the current player
					create a new temporary king piece
					overwrite the tmporary king piece critical attributes with those from the temporary moved piece
					overwrite the temporary moved piece with the temporary king piece
				update the location attribute of the temporary moved piece to the destination location
				add the temporary moved piece to the board at the destination location
			if this move did cause the piece to hit a mine
				~find the mine responsible and remove it
				for each piece at the move destination location
					if the piece is a mine
						if the piece owner is not the current player
							remove the piece
							stop looking through pieces at the destination location
				movedpiece has been destroyed so it should have no reference
				it is a new turn
			~check if this was a stationary move indicating the end of a turn
			if the move starting location is the same as the move starting location
				it is a new turn
			overwrite the temporary last piece with the temporary moved piece
			extract the move properties of hit mine, tranformed to king, and jumped locations
		return the extracted move properties
		*/
		
		//declarations or resets
		this.currentMove = null;
		ArrayList<String> moveresults = new ArrayList<String>();
		Piece movedpiece = null;
		ArrayList<Piece> jumpedpieces = new ArrayList<Piece>();
		LinkedList<Piece> tmppieces = new LinkedList<Piece>();
		
		System.out.println("GAME: newMove=" + newMove.locations.get(newMove.locations.size()-1));
		for (int i=0; i<this.AvailableMoves.size(); ++i){
			System.out.println("GAME: AvailableMoves[" + i + "]=" + this.AvailableMoves.get(i).locations.get(this.AvailableMoves.get(i).locations.size()-1));
		}
		
		//match move sent to us with our existing list of AvailableMoves
		//  since GUI was only sent a series of destination locations to determine move,
		//  we should match only the last locations
		//retrieve input ending location
		Location tmpnewloc = newMove.locations.get(newMove.locations.size()-1);
		matchmove: for (int i=0; i<this.AvailableMoves.size(); ++i){
			//retrieve the available move ending location
			Location tmpavailloc = this.AvailableMoves.get(i).locations.get(this.AvailableMoves.get(i).locations.size()-1);
			if (tmpavailloc.equals(tmpnewloc) && tmpavailloc.board == tmpnewloc.board){
				System.out.println("GAME: Input move matched with an available move!");
				this.currentMove = this.AvailableMoves.get(i);
				break matchmove;
			}
		}
		//if cannot match
		if (currentMove == null){
			//print a message informing about this strange situation which likely indicates an error
			System.out.println("GAME: Input move NOT matched with an available move!");
			//send back an empty list of move properties
			moveresults.add("" + false);
			moveresults.add("" + false);
		}else{
			//if matched
			//add the move to the moves log
			this.gameMoves.addMove(this.currentMove);
			//~update stats and counters to reflect the move that is about to be made
			//~make the move in parallel to updating the stats in counters
			//increment the total moves stat for the current player
			if(this.currentPlayer.getName().equals(this.players.get(0).getName())){
				++tm1;
			}else{
				++tm2;
			}
			//increment the move number
			++this.moveNumber;
			//~check for jumps
			//if move locations size is larger than 2 then there is a jump
			if (this.currentMove.locations.size() > 2){
				//for each jumped location in the move locations
				scanjumps: for (int i=1; i<this.currentMove.locations.size()-1; ++i){
					//increment the jumps stat for the current player
					if(this.currentPlayer.getName().equals(this.players.get(0).getName())){
						++j1;
					}else{
						++j2;
					}
					//~peek at what was jumped
					//for each piece residing on the board at the jumped location
					//extract the list of pieces so that they are readily available
					tmppieces = (this.getBoard(this.currentMove.locations.get(i).board)).getPieces(this.currentMove.locations.get(i));
					if (tmppieces == (this.getBoard(this.currentMove.locations.get(i).board)).getPieces(this.currentMove.locations.get(i))){
						System.out.println("GAME: list of pieces for jumped location matches the extracted list reference");
					}else{
						System.out.println("GAME: list of pieces for jumped location DOES NOT match the extracted list reference");
					}
					scanpieces: for (int j=0; j<tmppieces.size(); ++j){
						//~check for jumped kings
						//if the piece owner is not the current player
						if (!tmppieces.get(j).owner.equals(this.currentPlayer.getName())){
							//if the piece is jumpable
							if (tmppieces.get(j).jumpable){
								//if the piece is a king
								if (tmppieces.get(j).getClass().getName().equals("King")){
									//increment the kings destroyed stat for the current player
									if(this.currentPlayer.getName().equals(this.players.get(0).getName())){
										++kd1;
									}else{
										++kd2;
									}
								}
								//add the piece to the list of jumped pieces
								jumpedpieces.add(tmppieces.get(j));
								//remove the piece from the board
								this.getBoard(tmppieces.get(j).location.board).removePiece(tmppieces.get(j), tmppieces.get(j).location);
								//stop looking through pieces at this jumped location
								break scanpieces;
							}
						}
					}
				}
			}
			//~move the piece
			//for each piece residing on the board at the starting location
			//extract the list of pieces so that they are readily available
			tmppieces = (this.getBoard(this.currentMove.locations.get(0).board)).getPieces(this.currentMove.locations.get(0));
			if (tmppieces == (this.getBoard(this.currentMove.locations.get(0).board)).getPieces(this.currentMove.locations.get(0))){
				System.out.println("GAME: list of pieces for start location matches the extracted list reference");
			}else{
				System.out.println("GAME: list of pieces for start location DOES NOT match the extracted list reference");
			}
			scanstarters: for (int i=0; i<tmppieces.size(); ++i){
				//if the piece owner is the current player
				if (tmppieces.get(i).owner.equals(this.currentPlayer.getName())){
					//if the piece can move (move range larger thn 0)
					if (tmppieces.get(i).moveRange > 0){
						//if move locations size is larger than 2 then there was a jump
						if (this.currentMove.locations.size() > 2){
							//update the piece has jumped property to true
							tmppieces.get(i).hasJumped = true;
						}
						//temporarily store a copy of the piece
						movedpiece = tmppieces.get(i);
						if ((this.getBoard(this.currentMove.locations.get(0).board)).getPieces(this.currentMove.locations.get(0)).get(i).equals(movedpiece)){
							System.out.println("GAME: moved piece matches axtracted piece reference");
						}else{
							System.out.println("GAME: moved piece DOES NOT match axtracted piece reference");
						}
						//remove the piece from the board
						this.getBoard(tmppieces.get(i).location.board).removePiece(tmppieces.get(i), tmppieces.get(i).location);
						//stop looking through pieces at the starting location
						break scanstarters;
					}
				}
			}
			//~check if we warped
			//if the move destination location board is not the same as the move starting location board
			if (this.currentMove.locations.get(0).board != this.currentMove.locations.get(this.currentMove.locations.size()-1).board){
				System.out.println("GAME: Warp detected and recorded.");
				//update the temporary moved piece has warped property to true
				movedpiece.hasWarped = true;
				//increment the warps stat for the current player
				if(this.currentPlayer.getName().equals(this.players.get(0).getName())){
					++w1;
				}else{
					++w2;
				}
			}
			//~decide if we need to place the piece
			//if this move did not cause the piece to hit a mine
			if (!this.currentMove.hitMine){
				//~check if we need to change the piece
				//if this move caused the piece to transform into a king and the piece is not already a king
				if (this.currentMove.transformToKing && !movedpiece.getClass().getName().equals("King")){
					//increment the kings created stat for the current player
					if(this.currentPlayer.getName().equals(this.players.get(0).getName())){
						++kc1;
					}else{
						++kc2;
					}
					//create a new temporary king piece
					King tmpking = new King(movedpiece.owner, "" + movedpiece.location.x, "" + movedpiece.location.y, "" + movedpiece.location.board, movedpiece.direction);
					//overwrite the tmporary king piece critical attributes with those from the temporary moved piece
					tmpking.hasWarped = movedpiece.hasWarped;
					tmpking.hasJumped = movedpiece.hasJumped;
					tmpking.location = movedpiece.location;
					//overwrite the temporary moved piece with the temporary king piece
					movedpiece = tmpking;
				}
				//update the location attribute of the temporary moved piece to the destination location
				movedpiece.location = this.currentMove.locations.get(this.currentMove.locations.size()-1);
				//add the temporary moved piece to the board at the destination location
				this.getBoard(movedpiece.location.board).addPiece(movedpiece, movedpiece.location);
				System.out.println("GAME: moved piece properties: hasJumped=" + movedpiece.hasJumped + "hasWarped=" + movedpiece.hasWarped);
				System.out.println("GAME: board piece properties: hasJumped=" + this.getBoard(movedpiece.location.board).getPieces(movedpiece.location).get(0).hasJumped + "hasWarped=" + this.getBoard(movedpiece.location.board).getPieces(movedpiece.location).get(0).hasWarped);
			}else{
				System.out.println("GAME: smart mine was hit!");
				//~find the mine responsible and remove it
				//for each piece at the move destination location
				Location tmpmineloc = this.currentMove.locations.get(this.currentMove.locations.size()-1);
				tmppieces = (this.getBoard(tmpmineloc.board).getPieces(tmpmineloc));
				scandestination: for (int i=0; i<tmppieces.size(); ++i){
					System.out.println("GAME: looking at " + tmppieces.get(i).getClass().getName() + " owned by " + tmppieces.get(i).owner);
					//if the piece is a mine
					if (tmppieces.get(i).getClass().getName().equals("Mine")){
						//if the piece owner is not the current player
						if (!tmppieces.get(i).owner.equals(movedpiece.owner)){
							System.out.println("GAME: found smart mine to remove");
							//remove the piece
							this.getBoard(tmppieces.get(i).location.board).removePiece(tmppieces.get(i), tmppieces.get(i).location);
							//stop looking through pieces at the destination location
							break scandestination;
						}
					}
				}
				//movedpiece has been destroyed so it should have no reference
				movedpiece = null;
				//it is a new turn
				gameMoves.nextTurn();
				if(currentPlayer.equals(players.get(1)))
				{
					setPlayer(0);
				}
				else
				{
					setPlayer(1);
				}
				moveNumber=1;
			}
			//~check if this was a stationary move indicating the end of a turn
			//if the move starting location is the same as the move starting location
			if (this.currentMove.locations.get(0).equals(this.currentMove.locations.get(this.currentMove.locations.size()-1))){
				System.out.println("GAME: current move is a stationary move, setting up new turn");
				//it is a new turn
				gameMoves.nextTurn();
				if(currentPlayer.equals(players.get(1)))
				{
					setPlayer(0);
				}
				else
				{
					setPlayer(1);
				}
				moveNumber=1;
			}
			//overwrite the temporary last piece with the temporary moved piece
			this.lastPiece = movedpiece;
			//extract the move properties of hit mine, tranformed to king, and jumped locations
			moveresults.add("" + this.currentMove.hitMine);
			moveresults.add("" + this.currentMove.transformToKing);
			extractjumps: for (int i=0; i<jumpedpieces.size(); ++i){
				Piece tmppiece = jumpedpieces.get(i);
				moveresults.add(tmppiece.getClass().getName() + "," + tmppiece.owner + "," + tmppiece.location.x + "," + tmppiece.location.y + "," + tmppiece.location.board);
			}
		}
		for (int i=0; i<moveresults.size(); ++i){
			System.out.println("GAME: moveresults[" + i + "] = " + moveresults.get(i));
		}
		//return the extracted move properties
		return moveresults;
		
		
		
		/*
		if(currentPlayer.getName().equals(players.get(0).getName()))
		{
			tm1++;
		}
		else
		{
			tm2++;
		}

		

		//The return string which represents what happened, hold Type,Owner,X,Y,Z locations if a piece was jumped
		//otherwise it is an empty string
		ArrayList<String> whatHappened=new ArrayList<String>();
		//the currentMove attribute is set to the incoming move
		currentMove=newMove;

		String temp= new String("");
		//the present and future location
		Location currentLocation,futureLocation;
		//this will hold the index of where the board is
		int moveable,numberOfLocations;
		//Since the Piece class takes the futureLocation as a string we need futureLoc to represent
		// that String. The X,Y,Z are the coordinates we will use if we create a king piece.
		String Owner,X,Y,Z;
		//a dummyPiece we will use if we need to make a king piece
		Piece dummyPiece,Dummy;
		//sets the currentLocation to where the piece is currently located.
		currentLocation = currentPiece.location;
		//sets the boardInt to the named of the current board(which is also the index of where it is in our ArrayList)

		//The number of Locations
		numberOfLocations= newMove.getLocations().size();

		//The following extract the future location from the Move that was passed to this method. The location that is in
		// the last index of the ArrayList<Location> within moves. After we have the Location type we convert it to a String
		// so that we may pass it to the Piece Class.
		futureLocation = newMove.getLocations().get(newMove.getLocations().size()-1);

		//if the boards have changed then the piece has warped
		if(currentLocation.board!=futureLocation.board)
		{
			currentPiece.hasWarped = true;
			if(currentPlayer.getName().equals(players.get(0).getName()))
			{
			w1++;
			}
			w2++;

		}

		

		//if the size of the array is bigger than 2, there is a jump to be made
		
		for(int t=0;t<AvailableMoves.size();t++)
		{
			System.out.println("GAME: enter avil move loop");
			if(AvailableMoves.get(t).locations.size()>2)
			{
				System.out.println("GAME: enter avil move loop sub1");
			if((AvailableMoves.get(t).locations.get(2).position.equals(newMove.locations.get(1).position)) && (AvailableMoves.get(t).locations.get(2).board == (newMove.locations.get(1).board)))
			{
				System.out.println("GAME: enter avil move loop sub2");
					Move jumpMove=AvailableMoves.get(t);
					//Piece jumpedPiece=getBoard(currentLocation.getBoard()).getPieces(jumpMove.getLocations().get(jumpMove.getLocations().size()-2).position).get(0);
					//Piece jumpedPiece=getBoard(jumpMove.locations.get(1).getBoard()).getPieces(jumpMove.getLocations().get(2).position).get(0);
					Piece jumpedPiece=getBoard(jumpMove.locations.get(1).getBoard()).getPieces(jumpMove.locations.get(1).position).get(0);
					System.out.println("GAME: thinks jumpedpiece is at " + jumpedPiece.location.position + " ^ " + jumpedPiece.location.board);
					//Removes the jumped piece
					getBoard(currentLocation.getBoard()).removePiece(jumpedPiece, (jumpMove.getLocations().get(jumpMove.getLocations().size()-2).position));
					//Set the hasJumped boolean to true
					currentPiece.hasJumped = true;
					temp=jumpedPiece.getClass().getName()+","+jumpedPiece.owner+","+jumpedPiece.location.getX()+","+jumpedPiece.location.getY()+","+jumpedPiece.location.getBoard();
					if(currentPlayer.getName().equals(players.get(0).getName()))
					{
						j1++;
					}
					else
					{
						j2++;
					}
					//If the piece being jumped is a King add 1 to kings destroyed
					Piece dummy = new King("0","0","0","0",1); //just a dummy piece so i can compare the jumped piece to a king
					//if the jumped piece is a king add 1 to kings destroyed depending on the player
					if(jumpedPiece.getClass().equals(dummy.getClass()))
					{
		
						if(currentPlayer.getName().equals(players.get(0).getName()))
						{
							kd1++;
						}
						else
						{
							kd2++;
						}
					}
				}
			}
				
		}

		if(checkers.validateMine(futureLocation))
		{

			Piece dummyMine = getBoard(currentLocation.getBoard()).getPieces(futureLocation.position).get(0);

			//Since the piece landed on a mine we set the first boolean to true, and second to false
			//since it cannot become a king now. In addition if a jump was made previously
			//we append it to the end of the ArrayList
			whatHappened.add(0,"true");
			whatHappened.add(1,"false");
			newMove.hitMine=true;
			//remove the mine
			getBoard(currentLocation.getBoard()).removePiece(dummyMine, dummyMine.location.position);
			Dummy=getBoard(currentLocation.getBoard()).getPieces(currentLocation.position).get(0);
			//Remove the Piece
			getBoard(currentLocation.getBoard()).removePiece(Dummy, currentPiece.location.position);
			Piece dummy = new King("0","0","0","0",1); //just a dummy piece so i can compare the jumped piece to a king

			if(currentPiece.getClass().equals(dummy.getClass()))
			{

				if(currentPlayer.getName().equals(players.get(1).getName()))
				{
				kd1++;
				}
				else
				{
				kd2++;
				}
			}

			//Since the current play just blew up, we switch players and set the move
			//number to 1
			if(currentPlayer.equals(players.get(1)))
			{
				setPlayer(0);
			}
			else
			{
				setPlayer(1);
			}
			moveNumber=1;

		}
		else
		{
			//if the validateKing method is true (a checker has reached the opposite side)
			// then delete the checker and replace it with a king otherwise delete the checker and
			// replace it with another checker
			if(checkers.validateKing(futureLocation, currentPiece))
			{
				newMove.transformToKing=true;
				//sets the owner to whoever owns the current piece
				Owner=currentPiece.getOwner();
				//removes the currentPiece from the currentLocation

				Dummy=getBoard(currentLocation.getBoard()).getPieces(currentLocation.position).get(0);
				getBoard(currentLocation.getBoard()).removePiece(Dummy, Dummy.location.position);
				//The X,Y,Z are set from where the previous checker landed "futureLocation"
				X=""+futureLocation.getX();
				Y=""+futureLocation.getY();
				Z=""+futureLocation.getBoard();
				//sets the dummyPiece to our new King
				if(currentPlayer.equals(players.get(0)))
				{
					dummyPiece = new King(currentPlayer.getName(),X,Y,Z,1);
				}
				else
				{
					dummyPiece = new King(currentPlayer.getName(),X,Y,Z,-1);
				}
				//If the piece has warped this turn set hasWarped to true
				if(currentPiece.hasWarped)
				{
					dummyPiece.hasWarped=true;
				}
				//If the piece has jumped this turn set hasJumped to true
				if(currentPiece.hasJumped)
				{
					dummyPiece.hasJumped=true;
				}
				//Sets the lastPiece attribute to our currentPiece, its for future use
				lastPiece=dummyPiece;
				//adds a King to the futureLocation
				addPiece(dummyPiece,getBoard(futureLocation.getBoard()));
				//Since we did not land on a mine we set the first boolean to false
				// we are making a king so we set the second string to true
				whatHappened.add(0,"false");
				whatHappened.add(1,"true");
				if(currentPlayer.getName().equals(players.get(1).getName()))
				{
					kc1++;
				}
				else
				{
					kc2++;
				}
			}
			else
			{
				//both booleans are false since nothing special happened
				whatHappened.add(0,"false");
				whatHappened.add(1,"false");

				//sets the owner to whoever owns the current piece
				Owner=currentPiece.getOwner();

				if(currentPlayer.equals(players.get(0)))
				{
					moveable=1;
				}
				else
				{
					moveable=-1;
				}
			//Remove the Piece from its current Location
				for(int x=0; x<boards.get(0).Positions.length; ++x){
				for(int y=0; y<boards.get(0).Positions[x].length; ++y){
				System.out.print(boards.get(0).Positions[x][y].size());
				}System.out.println("");}

				Dummy=getBoard(currentLocation.getBoard()).getPieces(currentLocation.position).get(0);
				getBoard(currentLocation.getBoard()).removePiece(Dummy, Dummy.location.position);
				//The X,Y,Z are set to where the currentPiece landed "futureLocation"
				X=""+futureLocation.getX();
				Y=""+futureLocation.getY();
				Z=""+futureLocation.getBoard();
				//sets the dummyPiece to our new Checker
				dummyPiece = new Checker(Owner,X,Y,Z,moveable);

				//If the piece has warped this turn set hasWarped to true
				if(currentPiece.hasWarped)
				{
					dummyPiece.hasWarped=true;
				}
				//If the piece has jumped this turn set hasJumped to true
				if(currentPiece.hasJumped)
				{
					dummyPiece.hasJumped=true;
				}
				//Sets the lastPiece attribute to our currentPiece, its for future use
				lastPiece=dummyPiece;
				//add a checker to the future location
				addPiece(dummyPiece,getBoard(futureLocation.getBoard()));


			}

			//If the piece that was moved has another jump available don't change the current player
			//and increment the moveNumber by 1
			if(checkers.getAvailableMoves(dummyPiece,moveNumber++).size()!=0)
			{
				moveNumber=moveNumber+1;
			}
			// If there are no jumps to be made after the Piece has finished, change players
			//and set the jump number back to 1
			else
			{
				if(currentPlayer.equals(players.get(1)))
				{
					currentPlayer=players.get(0);
					setPlayer(0);
				}
				else
				{
					currentPlayer=players.get(1);
					setPlayer(1);
				}
				moveNumber=1;
			}
		}
		System.out.println("GAME: temp= " + temp);
		if (!temp.equals("")){
			whatHappened.add(temp);
		}
		gameMoves.addMove(newMove);
		return whatHappened;
		*/
	}

	public Boolean addBoards(int numberofBoards, Dimension boardSize) //Creates Boards to be used for the game
	{
		Board neededBoard;
		boardsSize=boardSize;
		for(int i=0;i<numberofBoards;i++)//loops through and adds Boards to the "boards" ArrayList
		{
			neededBoard=new Board(i,boardSize);
			boards.add(i,neededBoard);
		}
		checkers=new Rules(boards);
		checkers.setPieces(players);
		return true;




	}



	public ArrayList<Integer> getPieceCounter()
	{
		//Checker,King,Mine,BlockedZone,SafeZone
		ArrayList<Integer> pieceCount= new ArrayList<Integer>();
		pieceCount.add(checkers.getPiecesAvailable("Checker",currentPlayer.getName()));
		pieceCount.add(checkers.getPiecesAvailable("King",currentPlayer.getName()));
		pieceCount.add(checkers.getPiecesAvailable("Mine",currentPlayer.getName()));
		pieceCount.add(checkers.getPiecesAvailable("BlockedZone",currentPlayer.getName()));
		pieceCount.add(checkers.getPiecesAvailable("SafeZone",currentPlayer.getName()));

		return pieceCount;

	}

	public void setPlayer(int player)
	{
		if(player==0)
		{
			checkers.setCurrentPlayer(players.get(0));
			currentPlayer= players.get(0);
		}
		if(player==1)
		{
			checkers.setCurrentPlayer(players.get(1));
			currentPlayer=players.get(1);
		}


	}

	public ArrayList<ArrayList<Integer>> getStats()
	{
		ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
		results.add(new ArrayList<Integer>());//add two empty arraylists for two players
		results.add(new ArrayList<Integer>());
		results.get(0).add(tm1);
		results.get(0).add(w1);
		results.get(0).add(j1);
		results.get(0).add(kc1);
		results.get(0).add(kd1);
		results.get(1).add(tm2);
		results.get(1).add(w2);
		results.get(1).add(j2);
		results.get(1).add(kc2);
		results.get(1).add(kd2);

		return results;
	}

	public void randomizePlacement()
	{
		Random rand=new Random();
		int x,y,z; //coords to be used for the pieces
		Location randomLoc;
		Piece dummyPiece; //dummy piece to be used for playing pieces randomly
		LinkedList<Piece> piecelist = null;
		boolean invalidspot = false;

		//currentPlayer=players.get(0);
		while(getPieceCounter().get(0)!=0)//loop through and place checkers for player 1
		{
			x=Math.abs(rand.nextInt()%boardsSize.width);
			y=Math.abs(rand.nextInt()%boardsSize.height);
			z=Math.abs(rand.nextInt()%2);
			if(currentPlayer.equals(players.get(0)))
			{
				dummyPiece = new Checker(currentPlayer.getName(),""+x,""+y,""+z,1);
			}
			else
			{
				dummyPiece = new Checker(currentPlayer.getName(),""+x,""+y,""+z,-1);
			}
			randomLoc = new Location(x,y,z);
			piecelist = this.getBoard(randomLoc.board).getPieces(randomLoc);
			invalidspot = false;
			validatespot: for (int i=0; i<piecelist.size(); ++i){
				if(piecelist.get(i).getClass().getName().equals("Checker")){
					invalidspot = true;
					break validatespot;
				}
			}
			if (!invalidspot){
				addPiece(dummyPiece,getBoard(z));
			}
			//currentPlayer = players.get(0);//make sure player 1 is still placing pieces
		}
		while(getPieceCounter().get(1)!=0)//loop through and place checkers for player 1
		{
			x=Math.abs(rand.nextInt()%boardsSize.width);
			y=Math.abs(rand.nextInt()%boardsSize.height);
			z=Math.abs(rand.nextInt()%2);
			if(currentPlayer.equals(players.get(0)))
			{
				dummyPiece = new King(currentPlayer.getName(),""+x,""+y,""+z,1);
			}
			else
			{
				dummyPiece = new King(currentPlayer.getName(),""+x,""+y,""+z,-1);
			}
			randomLoc = new Location(x,y,z);
			piecelist = this.getBoard(randomLoc.board).getPieces(randomLoc);
			invalidspot = false;
			validatespot: for (int i=0; i<piecelist.size(); ++i){
				if(piecelist.get(i).getClass().getName().equals("Checker")
					|| piecelist.get(i).getClass().getName().equals("King")){
					invalidspot = true;
					break validatespot;
				}
			}
			if (!invalidspot){
				addPiece(dummyPiece,getBoard(z));
			}
			//currentPlayer = players.get(0);//make sure player 1 is still placing pieces
		}
		while(getPieceCounter().get(2)!=0)//loop through and place checkers for player 1
		{
			x=Math.abs(rand.nextInt()%boardsSize.width);
			y=Math.abs(rand.nextInt()%boardsSize.height);
			z=Math.abs(rand.nextInt()%2);
			if(currentPlayer.equals(players.get(0)))
			{
				dummyPiece = new Mine(currentPlayer.getName(),""+x,""+y,""+z,1);
			}
			else
			{
				dummyPiece = new Mine(currentPlayer.getName(),""+x,""+y,""+z,-1);
			}
			randomLoc = new Location(x,y,z);
			addPiece(dummyPiece,getBoard(z));
			//currentPlayer = players.get(0);//make sure player 1 is still placing pieces
		}
		while(getPieceCounter().get(3)!=0)//loop through and place checkers for player 1
		{
			x=Math.abs(rand.nextInt()%boardsSize.width);
			y=Math.abs(rand.nextInt()%boardsSize.height);
			z=Math.abs(rand.nextInt()%2);
			if(currentPlayer.equals(players.get(0)))
			{
				dummyPiece = new BlockedZone(currentPlayer.getName(),""+x,""+y,""+z,1);
			}
			else
			{
				dummyPiece = new BlockedZone(currentPlayer.getName(),""+x,""+y,""+z,-1);
			}
			randomLoc = new Location(x,y,z);
			piecelist = this.getBoard(randomLoc.board).getPieces(randomLoc);
			invalidspot = false;
			validatespot: for (int i=0; i<piecelist.size(); ++i){
				if(piecelist.get(i).getClass().getName().equals("Checker")
					|| piecelist.get(i).getClass().getName().equals("King")
					|| piecelist.get(i).getClass().getName().equals("Mine")){
					invalidspot = true;
					break validatespot;
				}
			}
			if (!invalidspot){
				addPiece(dummyPiece,getBoard(z));
			}
			//currentPlayer = players.get(0);//make sure player 1 is still placing pieces
		}
		while(getPieceCounter().get(4)!=0)//loop through and place checkers for player 1
		{
			x=Math.abs(rand.nextInt()%boardsSize.width);
			y=Math.abs(rand.nextInt()%boardsSize.height);
			z=Math.abs(rand.nextInt()%2);
			if(currentPlayer.equals(players.get(0)))
			{
				dummyPiece = new SafeZone(currentPlayer.getName(),""+x,""+y,""+z,1);
			}
			else
			{
				dummyPiece = new SafeZone(currentPlayer.getName(),""+x,""+y,""+z,-1);
			}
			randomLoc = new Location(x,y,z);
			piecelist = this.getBoard(randomLoc.board).getPieces(randomLoc);
			invalidspot = false;
			validatespot: for (int i=0; i<piecelist.size(); ++i){
				if(piecelist.get(i).getClass().getName().equals("Mine")
					|| piecelist.get(i).getClass().getName().equals("BlockedZone")){
					invalidspot = true;
					break validatespot;
				}
			}
			if (!invalidspot){
				addPiece(dummyPiece,getBoard(z));
			}
			//currentPlayer = players.get(0);//make sure player 1 is still placing pieces
		}

	}
	public void setInitialBoard()
	{
		//gameMoves.setInitialBoard(boards);
		//need to loop through every entry of the boards and make an exact copy
		ArrayList<Board> tmpboards = new ArrayList<Board>();
		for (int b=0; b<this.boards.size(); ++b){
			Board refboard = this.boards.get(b);
			Board tmpboard = new Board(refboard.ID, refboard.size);
			tmpboard.Pieces = (LinkedList<Piece>)refboard.Pieces.clone();
			for (int x=0; x<refboard.size.width; ++x){
				for (int y=0; y<refboard.size.height; ++y){
					tmpboard.Positions[x][y] = (LinkedList<Piece>)refboard.Positions[x][y].clone();
				}
			}
			tmpboards.add(tmpboard);
		}
		gameMoves.setInitialBoard(tmpboards);
	}
	public MovesLog getMovesLog()
	{
		return gameMoves;
	}


}